package mya.mes.mdc.logic.mqtt;

import com.alibaba.fastjson.JSONObject;
import mya.common.util.Utils;
import mya.mes.mdc.local.alarm.MdcAlarmResult;
import mya.mes.mdc.local.mongodb.MongoDbService;
import mya.mes.mdc.logic.alarm.filter.AlarmFilter;
import mya.mes.mdc.logic.alarm.mqtt.MqttAlarmProcessor;
import mya.mes.mdc.mongodb.Mongo;
import mya.mes.mdc.mqtt.MqttClientManager;
import mya.mes.mdc.share.mqttread.MqttMsgProcessor;
import mya.mes.mdc.share.plc.PlcTagVoFilter;
import mya.mes.mdc.share.plc.PlcTagVoProcessor;
import mya.mes.mdc.share.vo.mqtt.MqttMsgReceived;
import mya.mes.mdc.share.vo.plc.PlcTagVo;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class MdcMqttDefaultProcessor implements MqttMsgProcessor {

    private final Long zoneId = 1L;

    private final DataSaveToMongoProcessor dataProcessor;

    private final WebsocketBroadCast websocketBroadCast;

    private final List<PlcTagVoProcessor> plcTagVoProcessorList = new ArrayList<>();

    private PlcTagVoFilter alarmTagVoFilter;
    private final MqttAlarmProcessor alarmProcessor;

    public MdcMqttDefaultProcessor() {
        alarmProcessor = new MqttAlarmProcessor(zoneId);
        dataProcessor = new DataSaveToMongoProcessor();
        websocketBroadCast = new WebsocketBroadCast();
        alarmTagVoFilter = new AlarmFilter();
    }

    @Override
    public Boolean accept(Long zoneId) {
        return this.zoneId.equals(zoneId);
    }

    @Override
    public void mqttReceive(MqttMsgReceived mqttMsg) throws Exception {
        final Long mqttMsgId = mqttMsg.mqttMsgId;
        List<PlcTagVo> voList = null;
        MdcAlarmResult alarmResult = null;
        try {
            voList = MqttClientManager.getInstance().getDataConverter()
                    .processMsg(mqttMsg.mqttTopic, mqttMsg.mqttContent);
            //保存指令到mongdb中。
            MongoDbService mongoDbService = Mongo.getInstance().getMongoDbService();
            JSONObject jsonObject = JSONObject.parseObject(mqttMsg.mqttContent);
            jsonObject.put("topicName",mqttMsg.mqttTopic);
            jsonObject.put("_id",mqttMsg.mqttMsgId);
            JSONObject jsonObject_ = mongoDbService.saveMqttReceivedMsg(jsonObject);

            Long mqttSavedId = jsonObject.getLong("_id");
            String mqttSavedColl = jsonObject.getString("SAVED_MQTT_COLL_NAME");
            String topicName = mqttMsg.mqttTopic;
            //解析报警指令
            alarmProcessor.process(topicName,mqttSavedColl,mqttSavedId,jsonObject_);
//            dataProcessor.process(mqttMsgId, voList);
//            alarmResult = processAlarm(mqttMsgId, voList);
            //取消3d的数据推送
//            for (PlcTagVoProcessor processor : plcTagVoProcessorList) {
//                processor.process(mqttMsgId, voList);
//            }
        } catch (Throwable t) {
            t.printStackTrace();
            return;
        }
        websocketBroadCast.broadcast(mqttMsgId, voList, alarmResult);
    }

    private MdcAlarmResult processAlarm(Long mqttMsgId, List<PlcTagVo> voList) throws Exception {
        List<PlcTagVo> alarmVoList = alarmTagVoFilter.filter(voList);
        if (Utils.isNullOrEmpty(alarmVoList)) {
            return null;
        }
        return alarmProcessor.process(mqttMsgId, alarmVoList);
    }

    @Override
    public synchronized void addPlcTagVoProcessor(PlcTagVoProcessor processor) {

        if (processor == null || processor.getId() == null || processor.getId().isEmpty()) {
            return;
        }


        removePlcTagVoProcessor(processor);

        plcTagVoProcessorList.add(processor);
    }

    @Override
    public synchronized void removePlcTagVoProcessor(PlcTagVoProcessor processor) {
        if (processor == null || processor.getId() == null || processor.getId().isEmpty()) {
            return;
        }

        Iterator<PlcTagVoProcessor> it = plcTagVoProcessorList.iterator();

        while (it.hasNext()) {
            PlcTagVoProcessor tmp = it.next();

            if (processor.getId().equals(tmp.getId())) {
                it.remove();

                break;
            }
        }
    }

}
